package com.gxc.yunwei;

import com.alibaba.fastjson.JSONObject;
import com.gxc.utils.RestControllerResult;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.Data;

/**
 * 处理异常的发货单类.
 *
 * @author 宫新程
 * @since 2019/1/15 11:31 AM
 */
public class YunWei {

  /** 入参Dto. */
  @Data
  private static class ParamDto {
    private Integer ifEstore = 1;
    private Long memberId;
    private List<Long> orderIdList;
  }

  /** 处理异常的发货单. */
  public static void main(String[] args) throws Exception {
    // 通过io读取文件数据，放入入参List中.
    LinkedList<ParamDto> dataList =
        getParamsList(
            "E:\\My_Workspace\\MyTest\\Test_Mybatis\\src\\main\\java\\com\\gxc\\yunwei\\tmp.txt");
    // 提示总记录数，是否执行操作
    System.out.println("总记录数：" + dataList.size());
    System.out.print("是否全部执行（ Y / N ）：");
    Scanner sc = new Scanner(System.in);
    String execute = sc.next();
    // 关闭程序
    if (!"Y".equalsIgnoreCase(execute)) {
      System.out.println("程序关闭！");
      return;
    }
    // 执行操作
    execute(dataList);
    // 关闭资源
    sc.close();
  }

  /**
   * 通过io读取文件数据，放入入参List中.
   *
   * @param filePath 文件绝对路径.
   * @return 入参列表.
   */
  private static LinkedList<ParamDto> getParamsList(String filePath) throws Exception {
    // 用于存放数据的List
    LinkedList<ParamDto> dataList = new LinkedList<>();
    // 获取文件流，读文件，将数据放到linkedList中
    FileInputStream inputStream = new FileInputStream(new File(filePath));
    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
    String line;
    while ((line = br.readLine()) != null) {
      // 数据格式化，并放入链表中
      String[] array = line.split("\t");
      // 去除多余空格，并封装dto
      ParamDto dto = new ParamDto();
      dto.setMemberId(Long.parseLong(array[0].trim()));
      List<Long> orderIdList = new ArrayList<>();
      orderIdList.add(Long.parseLong(array[1].trim()));
      dto.setOrderIdList(orderIdList);
      dataList.addLast(dto);
    }
    br.close();
    return dataList;
  }

  /** 执行操作. */
  private static void execute(LinkedList<ParamDto> dataList) throws Exception {
    System.out.print("正在执行...");
    int success = 0;
    int error = 0;
    // 用于存放执行错误的数据
    List<ParamDto> errorDto = new ArrayList<>();
    // 用于存放错误信息
    Set<String> set = new HashSet<>();
    URL url =
        new URL(
            "http://www.yilihuo.com/ylh-cloud-service-goods/api/inner/stock/out-management/cancel-store-outbound-record-by-ids");
    for (ParamDto paramDto : dataList) {
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setDoInput(true);
      conn.setDoOutput(true);
      conn.setRequestMethod("POST");
      conn.setRequestProperty("Content-Type", "application/json");
      // 认证token
      conn.setRequestProperty(
          "Authorization",
          "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZW1iZXJfaWQiOjIwODcwMSwicmV0YWlsX21lbWJlcl9pZCI6MCwicmV0YWlsX2N1c3RvbWVyX2lkIjowLCJ1c2VyX25hbWUiOiI4ODAwMTM4MTc2IiwibWVtYmVyX25hbWUiOiLphrTpmbXluILlpKfpmpzplYfmgJ3liKnnlLXlmajllYbooYwiLCJhdXRob3JpdGllcyI6WyJyb2xlIl0sImNsaWVudF9pZCI6InByb2RfY2xvdWRfYXBpX2dhdGV3YXkiLCJzaG9wX2lkIjpudWxsLCJhdWQiOlsieWxoLWNsb3VkLXNlcnZpY2UtZ29vZHMiLCJ5bGgtY2xvdWQtc2VydmljZS1iaSIsInlsaC1jbG91ZC1zZXJ2aWNlLW9yZGVyIiwieWxoLWNsb3VkLW1ndC1zeXMtZGF0YSIsInlsaC1jbG91ZC1zZXJ2aWNlLWZ1bmQiLCJ5bGgtY2xvdWQtc2VydmljZS1wb2xpY3kiLCJ5bGgtY2xvdWQtc2VydmljZS1ub3RpY2UiLCJ5bGgtY2xvdWQtc2VydmljZS1wcmljZSIsInlsaC1jbG91ZC1zZXJ2aWNlLW9wZW5hcGkiLCJ5bGgtY2xvdWQtc2VydmljZS1kdWJibyIsInlsaC1jbG91ZC1tZ3QtZ2F0ZXdheSIsInlsaC1jbG91ZC1zZXJ2aWNlLWV4Y2hhbmdlIiwieWxoLWNsb3VkLXNlcnZpY2UtdXNlciIsInlsaC1jbG91ZC1zZXJ2aWNlLWJhc2UiXSwidXNlcl9pZCI6MTEwMzY2NTMwNSwicmV0YWlsX2N1c3RvbWVyX2NvZGUiOm51bGwsInNjb3BlIjpbInRlc3Qtc2NvcGUtcmVhZCIsInRlc3Qtc2NvcGUtd3JpdGUiXSwibmlja19uYW1lIjoieOKAhmzigIZr4oCGMTk4MzY3IiwiZXhwIjoxNTQ4MjA5NDYxLCJyZXRhaWxfY3VzdG9tZXJfbmFtZSI6bnVsbCwianRpIjoiZjYzOTk4ZDctNmVmMC00MjNmLTg3YjMtYTU0Nzg5MWJkZDQxIiwib3JpZ2luX2NsaWVudF9pZCI6InByb2RfY2xvdWRfYXBpX2dhdGV3YXkifQ.B8HEoq-pAthw4wn5GMyckYA-vFCWDS4VApuR3CuMu-leMDJvpYZg60kdpQu3Mim2QDTqKTLiiD-bwqDbqlEcQ1LcPcE3CpDt6i_3WhQlnb-xnwECcNmQg-J1PAPE6ITJWgDK2MItYdjS17OAnkm9mzhJ685fmtlzLSS3RJfhro3qOL5AION1bblMe2XzFggHtGlDbyyFqtymCn3HwdO6486indaLxcRCrup43qDfEppBgoSberS6V8LBhYhDojWDqViB_SnlhChINti4svBbMJkPyZpaOvS8hNVboTWtKge8LTpwjgMOKsluM7LHj_V0Xp9GmaI-Nv0ht0tJAe_-yw");

      // 发送请求参数
      String json = JSONObject.toJSONString(paramDto);
      OutputStream outputStream = conn.getOutputStream();
      outputStream.write(json.getBytes(StandardCharsets.UTF_8));
      outputStream.flush();

      // 获取返回结果.
      InputStream in = conn.getInputStream();
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
      String body = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator()));

      // 使用fastJson转换成Java对象，判断返回结果.
      RestControllerResult result = JSONObject.parseObject(body, RestControllerResult.class);
      if (result.getSuccess() && (Boolean) result.getData()) {
        success++;
      } else {
        error++;
        set.add(result.getErrorMsg());
        errorDto.add(paramDto);
      }
      // 关闭资源.
      outputStream.close();
      bufferedReader.close();
      conn.disconnect();
    }

    // 打印返回结果
    printResult(success, error, errorDto, set);
  }

  /** 打印结果. */
  private static void printResult(
      int success, int error, List<ParamDto> errorDto, Set<String> set) {
    System.out.println("\n执行成功：" + success + " 条，执行失败：" + error + " 条！");
    // 如果有错误，打印错误的信息.
    if (!errorDto.isEmpty() || !set.isEmpty()) {
      System.out.println("====== 错误信息 =====");
      set.forEach(System.out::println);
      System.out.println("====== 错误数据 =====");
      // 错误信息的 memberId 和 orderId
      errorDto.stream()
          .map(e -> e.getMemberId() + " " + e.getOrderIdList().get(0))
          .collect(Collectors.toList())
          .forEach(System.out::println);
    }
  }
}
